/* 
 * JUGJobs -- A Jobs Posting Application for Java Users Groups and Other Groups
 * $Id: LogFileWriter.java,v 1.2 2005/10/04 03:08:46 biglee Exp $
 * 
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the JUGJobs project.
 *
 * The Initial Developers of the Original Code are the members of the Triangle
 * Java User's Group in the RTP area of North Carolina.
 * Portions created by the Initial Developer are Copyright (C) 2005
 * the Initial Developers. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** 
 */
package org.jugjobs.controller;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author BigLee
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class LogFileWriter {
	  private static final int oneDayMillis = 24*60*60*1000;
	  //  TODO: with daylight savings time, make this 4*60* ...
	  private static final int gmtOffset = 5*60*60*1000;
	  private File thisFile;
	  private FileWriter writer;
	  private Timer timer = new Timer(true);
	  private String directoryName;
	  private SimpleDateFormat dateFormat = new SimpleDateFormat("yy-MM-dd");

	  LogFileWriter(String directoryName){
	    this.directoryName = directoryName; 
	    if (!(new File(directoryName)).exists()){
	      /* TODO: the following line fails to make the directory in Linux
	       */
	      (new File(directoryName)).mkdir();
	    }
	    makeFileAndWriter();
	    
	    //and now call makeFileAndWriter every midnight henceforth
	    TimerTask midnightTask = new TimerTask(){
	      public void run(){
	        makeFileAndWriter();
	      }
	    };  
	    long nowMillis = System.currentTimeMillis();
	    long millisPastMidnightHere = (nowMillis - gmtOffset)%oneDayMillis;
	    long nextMidnightMillis =
	        (nowMillis - millisPastMidnightHere) + oneDayMillis;
	    Date firstRunDate = new Date(nextMidnightMillis);  
	    timer.scheduleAtFixedRate(midnightTask, firstRunDate, oneDayMillis);
	  }
	  
	  private synchronized void makeFileAndWriter(){
	    FileWriter oldWriter = writer;
	    String fileNameBase = directoryName + File.separator +
	          dateFormat.format(new Date());
	    thisFile = new File(fileNameBase);
	    
	    try{
	      /* If a logfile for this date already exists (if thisFile.exists())
	       * then try to create a file with the same name but append by a ... z
	       * If a-z are all used up, throw an IOException.
	       */
	      boolean newFileCreated = false;
	      for (char appendChar = 'a';
	          !(newFileCreated = thisFile.createNewFile()) && appendChar <= 'z';
	           appendChar++)
	      {
	        thisFile = new File (fileNameBase + appendChar);      
	      }
	      if (!newFileCreated){
	        throw new IOException("File name suffixes a-z all used up for "+
	            fileNameBase);
	      }
	      
	      writer = new FileWriter(thisFile);
	      
	      if (oldWriter != null){
	        oldWriter.close();
	      }
	    }catch (IOException ioe){
	      throw new RuntimeException(
	          "Youch! working with thisFile: "+thisFile.toString(),ioe);
	    }
	  }// makeFileAndWriter()
	  
	  synchronized void writeln(String report){
	    try{
	      writer.write(report + "\r\n");
	      writer.flush();
	    }catch (IOException e){
	      throw new RuntimeException(
	        "This happened: "+e.toString()+"\nWhen trying to log:\n[\n" + 
	          report + "\n]");
	    }
	  }
	  
	  void close(){
	    try{writer.close();}catch(IOException e){};
	  }
	}